// -*- c-basic-offset: 2 default-tab-width: 2 indent-tabs-mode: t -*-
// vim: autoindent tabstop=2 noexpandtab shiftwidth=2 softtabstop=2
//===------------ Evaluator.h
//
//             This file is part of the reactor project
//                Author: R-Core Team
//
//===---------------------------------------------------------------------===//
#include <dirent.h>
#include <string.h>
#include <stdio.h>

#include "Const.h"
#include "File.h"

using namespace R;

const char* File::SearchPath;

const char *File::resolve(const char* fname){
	char buff[MAXNAMLEN+1];
	if(*fname == '~'){
		size_t size;
		char *res;
		buff[MAXNAMLEN] = 0; // Just to be sure
		res = stpcpy(buff, ConstPool::HomeDir);
		res = stpncpy(res, fname + 1, MAXNAMLEN - (res - buff)); // avoid overflow
		size = MAXNAMLEN - (res - buff) + 1;
		res = new char[MAXNAMLEN - (res - buff)];
		res = (char*) memcpy(res, buff, size);
		return const_cast<char*>(res);
	}
	return fname;
}

FILE *File::open(const char* fname, const char *mode){
	// FIXME this function only works in the unix world
	FILE *fd = fopen(fname, mode);	
	if(fd || *fname == '/')
		return fd;

	char buff[MAXNAMLEN+1];
	char *ptr;
	const char *next = SearchPath;
	int size = 0;
	buff[MAXNAMLEN] = 0; // Just to be sure

	do {
		ptr = stpcpy(buff, next); // fixme use stpncpy
		next += ptr - buff + 1;
		*ptr++ = '/';
		strcpy(ptr, fname);
		fd = fopen(buff, mode);	
	} while(!fd && *next);
	return fd;
}


void File::init(){
	Assert(!SearchPath, "Class 'File' is already initialized");

	const char *path = ConstPool::Path;
	const char *reactor = ConstPool::ReactorPath;
	int pathlen = strlen(path);
	int reactorlen = reactor ? strlen(reactor) : 0;
	int bufflen = pathlen + reactorlen + 3; // + 2;
	char *dst = new char[bufflen]; // + 1*2 for the lasts '\0' + 1 because we add one + 2 because I add '.'

	dst[bufflen - 1] = 0;

	for(int i = 0; i < reactorlen; i++){ // Copy reactor
		char c = reactor[i];
		dst[i] = (c == ':') ? 0 : c;
	}
	for(int i = 0; i < pathlen; i++){
		char c = path[i];
		dst[reactorlen + 1 + i] = (c == ':') ? 0 : c;
	}
	// For adding the final '.'
	//dst[bufflen - 3] = '.';
	//dst[bufflen - 2] = 0;

	SearchPath = dst;
}
